package com.hxd.qzg.interceptor;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hxd.qzg.common.Result;
import com.hxd.qzg.common.ServiceException;
import com.hxd.qzg.common.model.RequestLog;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.json.JFinalJson;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

public class ApiInterceptor implements Interceptor {

	private static final Log logger = LogFactory.get();

	private static final ExecutorService cachedThreadPool = Executors.newFixedThreadPool(5);

	public static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "javax.servlet.include.servlet_path";

	@Override
	public void intercept(Invocation inv) {
		// 打印参数
		logInfo(inv);
		Controller c = inv.getController();
		HttpServletResponse response = c.getResponse();
		response.addHeader("Access-Control-Allow-Origin", "*");
		HttpServletRequest request = c.getRequest();
		doFilterInternal(request);
		String returnResult = "";
		RequestLog log = new RequestLog();
		log.setCreateTime(new Date());
		log.setUpdateTime(new Date());
		log.setRequestUrl(request.getRequestURL().toString());
		log.setInParams((JFinalJson.getJson().toJson(c.getRequest().getParameterMap())));

		try {
			inv.invoke();
			returnResult = JFinalJson.getJson().toJson(c.getRender());
		} catch (Exception e) {
			returnResult = e.getMessage();
			logger.info(">>>> Exception " + e.getMessage() + " <<<<<<< ");
			this.bizException(e, c);
			return;
		} finally {
			log.setResult(returnResult);
			log.setReturnTime(new Date());
			saveRequestLog(log);
		}

	}

	// 不同业务异常 显示不同信息
	private void bizException(Exception e, Controller c) {
		if (e instanceof ServiceException) {
			ServiceException biz = (ServiceException) e;
			c.renderJson(Result.failure( biz.getMessage()));
		} else {
			logger.info(">> \n" + e.getMessage() + " ");
			c.renderJson(Result.failure("未知错误,请联系管理员"));
		}
	}

	public void saveRequestLog(RequestLog log) {
		cachedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					log.save();
				} catch (Exception e) {

				}
			}
		});
	}

	protected void doFilterInternal(HttpServletRequest request) {
		String path = request.getServletPath();
		logger.info("\n {} ", path);
	}

	private void logInfo(Invocation inv) {
		StringBuilder buffer = new StringBuilder();
		buffer.append("\n  请求参数： { cotroller: ").append(inv.getController()).append("cotrollerkey: ")
				.append(inv.getController().getControllerKey()).append(",methodNmae: ").append(inv.getMethodName())
				.append(",params: ")
				.append(JFinalJson.getJson().toJson(inv.getController().getRequest().getParameterMap())).append("}");
		logger.info(buffer.toString());
	}

}
